//
//  BaseQWHttpEngine.m
//  117goFramework
//
//  Created by Yunhai.Wu on 15/7/29.
//  Copyright (c) 2015年 117go. All rights reserved.
//

#import "BaseQWHttpEngine.h"
#import "QWNetworkActivityService.h"
#import "QWHttpEngineConfig.h"
#import "QWHttpUtil.h"


#define kGMRequestStringBoundary @"293iosfksdfkiowjksdf31jsiuwq003s02dsaffafass3qw"

@implementation BaseQWHttpEngine

-(instancetype)init {
    self = [super init];
    if (self) {
        _showNetworkActivityIndicator = [[QWHttpEngineConfig sharedInstance] defaultNetworkActivityEnabled];
    }
    return self;
}

-(BOOL)hasLoading {
    return _loading;
}

-(void)asynRequest:(id<IQWHttpRequest>)request responseClass:(Class)resClass responseBlock:(WJHttpEngineResponseBlock)resBlock {
    if (request && resClass != Nil && [resClass conformsToProtocol:@protocol(IQWHttpResponse)] && [request validateParams] && ![self hasLoading]) {
        
        __unsafe_unretained BaseQWHttpEngine *selfObject = self;
        self.resBlock = resBlock;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSError *error = nil;
            id<IQWHttpResponse> response = [selfObject syncRequestSystem:request responseClass:resClass error:&error];
            selfObject.resBlock(response,error);
            selfObject.resBlock = NULL;
        });
    }
}

-(id<IQWHttpResponse>)syncRequest:(id<IQWHttpRequest>)request responseClass:(Class)resClass error:(NSError *__autoreleasing *)error {
    return [self syncRequestSystem:request responseClass:resClass error:error];
}

-(id<IQWHttpResponse>)syncRequestSystem:(id<IQWHttpRequest>)request responseClass:(Class)resClass error:(NSError *__autoreleasing *)error {
    id<IQWHttpResponse> response = nil;
    if (request && resClass != Nil && [resClass conformsToProtocol:@protocol(IQWHttpResponse)] && [request validateParams]) {
        QWLogError(@"请求参数验证通过");
        if (_showNetworkActivityIndicator) {
            [[QWNetworkActivityService sharedInstance] start];
        }
        NSURLRequest *urlRequest = [BaseQWHttpEngine generateRequest:request];
        NSHTTPURLResponse *urlResponse = nil;
        NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&urlResponse error:error];
        if ([urlResponse statusCode] == 200) {
            NSMutableData *responseData = [[NSMutableData alloc] initWithData:data];
            response = [resClass parseResult:responseData];
        }
        if (_showNetworkActivityIndicator) {
            [[QWNetworkActivityService sharedInstance] stop];
        }
    } else {
        QWLogError(@"请求参数验证没通过");
        *error = [[NSError alloc] initWithDomain:@"SDK" code:11 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"参数错误",@"errorCode", nil]];
    }

    [[QWHttpFilterCore sharedInstance] filter:response];
    
    return response;
}
+(NSURLRequest*) generateRequest:(id<IQWHttpRequest>) request {
    NSString *httpURL = [request getURL];
    NSDictionary *params = [request getParams];
    NSDictionary *headers = [request getHeaders];
    NSString *httpMethod = [[request getMethod] uppercaseString];
    long timeoutInterval = [request getTimeoutDuration];
    NSDictionary *files = [request getUploadFiles];
    NSMutableURLRequest *urlRequest = nil;
    QWLogDebug(httpMethod);
    if ([httpMethod isEqualToString:@"GET"]) {
        if ([params count] > 0) {
            httpURL = [[NSString alloc] initWithFormat:@"%@?%@",httpURL,[QWHttpUtil stringWithFormEncodedComponents:params]];
        }
        QWLogDebug(@"HTTP URL:%@",httpURL);
        urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:httpURL] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:timeoutInterval];
    } else if ([httpMethod isEqualToString:@"POST"]) {
        QWLogDebug(@"HTTP URL:%@",httpURL);
        QWLogDebug(@"HTTP Parmas:%@",params);
        urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:httpURL] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:timeoutInterval];
        NSMutableData *bodyData = nil;
        if ([params count] > 0 || [files count] > 0) {
            bodyData = [[NSMutableData alloc] init];
            if ([files count] > 0) {
                [urlRequest setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kGMRequestStringBoundary] forHTTPHeaderField:@"Content-Type"];
                NSString *bodyLineStringBoundary = [NSString stringWithFormat:@"\r\n--%@", kGMRequestStringBoundary];//body开始字符串
                [bodyData appendData:[bodyLineStringBoundary dataUsingEncoding:NSUTF8StringEncoding]];
                for (id key in [params keyEnumerator]) {
                    id value = [params valueForKey:key];
                    if ([NSNull null] != (NSNull*)value) {
                        [bodyData appendData:[[NSString stringWithFormat:@"\r\nContent-Disposition: form-data; name=\"%@\"\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
                        [bodyData appendData:[[NSString stringWithFormat:@"Content-Type: application/json\r\n\r\n%@",value] dataUsingEncoding:NSUTF8StringEncoding]];
                        [bodyData appendData:[bodyLineStringBoundary dataUsingEncoding:NSUTF8StringEncoding]];
                    }
                }
                for (id key in [files keyEnumerator]) {
                    id value = [files valueForKey:key];
                    if ([NSNull null] != (NSNull*)value && [value isKindOfClass:[NSString class]]) {
                        NSData *fileData = [NSData dataWithContentsOfFile:value];
                        if ([fileData length] > 0) {
                            NSString *fileName = [[value componentsSeparatedByString:@"/"] lastObject];
                            [bodyData appendData:[[NSString stringWithFormat:@"\r\nContent-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",key,fileName] dataUsingEncoding:NSUTF8StringEncoding]];
                            [bodyData appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
                            [bodyData appendData:fileData];
                            [bodyData appendData:[bodyLineStringBoundary dataUsingEncoding:NSUTF8StringEncoding]];
                        }
                    }
                }
                if ([bodyData length] > 0)
                    [bodyData appendData:[@"--\r" dataUsingEncoding:NSUTF8StringEncoding]];
            } else {
                [urlRequest setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kGMRequestStringBoundary] forHTTPHeaderField:@"Content-Type"];
                NSString *bodyLineStringBoundary = [NSString stringWithFormat:@"\r\n--%@", kGMRequestStringBoundary];//body开始字符串
                [bodyData appendData:[bodyLineStringBoundary dataUsingEncoding:NSUTF8StringEncoding]];
                for (id key in [params keyEnumerator]) {
                    id value = [params valueForKey:key];
                    if ([NSNull null] != (NSNull*)value) {
                        [bodyData appendData:[[NSString stringWithFormat:@"\r\nContent-Disposition: form-data; name=\"%@\"\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
                        [bodyData appendData:[[NSString stringWithFormat:@"Content-Type: application/json\r\n\r\n%@",value] dataUsingEncoding:NSUTF8StringEncoding]];
                        [bodyData appendData:[bodyLineStringBoundary dataUsingEncoding:NSUTF8StringEncoding]];
                    }
                }
                if ([bodyData length] > 0) {
                    [bodyData appendData:[@"--\r" dataUsingEncoding:NSUTF8StringEncoding]];
                }
            }
        }
        [urlRequest setHTTPBody:bodyData];
    }
    [urlRequest setHTTPMethod:httpMethod];
    for (NSString *key in [headers keyEnumerator]) {
        if (![[key lowercaseString] isEqualToString:@"content-type"]) {
            [urlRequest setValue:[NSString stringWithFormat:@"%@",[headers objectForKey:key]] forHTTPHeaderField:key];
        }
    }
    return urlRequest;
}

@end
